<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BSpace
 *
 * @author ID59C
 */
class BSpace extends BNode {

    const All = 'all_space';

    private $type = null;
    public $category = null;
    //private $spaceUI = null;   
    public $data = array();
    public $spaceUI = null;
    public $apps = array();
    public $className = null;
    protected $currentApp = null;
    public $myId;

    public function __construct($id = NULL) {
        if ($id != NULL)
            $this->load($id);
    }

    public function getSpaceType($data = NULL) {
        if ($this->type == NULL) {
            //$groupContext = new BSpaceGroup();
            //$groupContext->name = BSpaceGroup::Group_SpaceType;
            $typeGroup = BSpaceGroup::find(BSpaceGroup::Group_SpaceType);
            $groups = $this->getGroups();
            foreach ($groups as $group) {
                if ($group->isChildOf($typeGroup))
                    $this->type = $group;
            }
        }
        return $this->type;
    }

    public function getCategory($data = null) {
        if ($this->category == NULL) {
            //$groupContext = new BSpaceGroup();
            //$groupContext->name = BSpaceGroup::Group_SpaceType;
            $categoryGroup = BSpaceGroup::find(BSpaceGroup::Group_Category);
            $groups = $this->getGroups();
            foreach ($groups as $id => $group) {
                if ($group->isChildOf($categoryGroup))
                    $this->category = $group;
            }
        }
        return $this->category;
    }

    public function getCurrentApp($data = NULL) {
        if ($this->currentApp instanceof BApp)
            $this->currentApp->setCurrentSpace($this);
        return $this->currentApp;
    }

    public function setCurrentApp($app) {
        $this->currentApp = $app;
    }

    public function getAppByName($name) {

        $app = isset($this->apps[$name]) ? $this->apps[$name] : NULL;

        if ($app == NULL) {
            //$relationEntity = new BRelationshipEntity($this, new BSpaceEngine());
            //$rEntities = BRelationshipEntity::findAll(array('mainObj' => $this, 'pairObjs' => new BApp()));
            $appList = $this->getApps();
            foreach ($appList as $app) {
                //$app = $rEntity->pairObj;
                if ($app->getName() == $name || strtolower(get_class($app)) == strtolower($name)) {
                    $this->apps[$name] = $app;
                    return $app;
                }
            }
        }

        return $app;
    }

    public function getApps($data = NULL) {
        //$relationEntity = new BRelationshipEntity($this, new BSpaceEngine());
        //$rEntities = BRelationshipEntity::findAll(array('mainObj' => $this, 'pairObjs' => new BApp()));
        $appList = BPairEntity::buildPairEntity($this, new BApp())->getPairObjList();
        //$apps = array();
        foreach ($appList as $app) {
            //$app = $rEntity->pairObj;
            //if ($app->getCurrentSpace() == NULL)
            $app->setCurrentSpace($this);
            $apps[$app->getId()] = $app;
        }
        if ($apps != NULL)
            return $apps;

        return FALSE;
    }

    /**
     * 
     * @param type $data
     * @return BApp
     */
    public function getSpaceEngine($data = NULL) {

        return $this->getAppByName('BSpaceEngine');
    }

    public function addApp($data) {

        if (is_numeric($data) && $data > 0)
            $app = BApp::getAppById($data);
        if ($data instanceof BApp)
            $app = $data;

        //$relationEntity = new BRelationshipEntity($this, $app);
        $pairEntity = BPairEntity::buildPairEntity($this, $app);
        $id = $pairEntity->save();
        $app->spaceId = $this->getId();
        //$app->save();
        //attach an event handler
        $this->onAddAppEvent = array($app, 'onAddToSpace');

        //raise event
        $event = new CEvent($this);
        $this->onAddAppEvent($event);

        return $app;
    }

    public function removeApp($data) {
        if (is_numeric($data) && $data > 0)
            $appId = $data;
        if ($data instanceof BApp)
            $appId = $data->getId();

        if ($appId != NULL && $appId > 0) {
            $mSApp = BMApp::model()->findByAttributes(array('space_id' => $this->getId(), 'app_id' => $appId));
            if ($mSApp != NULL) {
                $mSApp->status = BStatus::Status_Object_Deleted;
                $result = $mSApp->save();
                if ($result != NULL) {
                    //attache event handler
                    $app = new BApp($appId);
                    $this->onAddAppEvent = array($app, 'onRemoveApp');

                    //raise event
                    $event = new CEvent($this);
                    $this->onRemoveAppEvent($event);

                    return $result;
                }
            }
        }
        return FALSE;
    }

    public function onAddAppEvent($event) {
        $this->raiseEvent('onAddAppEvent', $event);
    }

    public function onRemoveAppEvent($event) {
        $this->raiseEvent('onRemoveAppEvent', $event);
    }

    /**
     * @return BUIManager Description
     * @param type $data
     */
    public function getUIManager($data = NULL) {
        if ($this->spaceUI == null)
            $this->spaceUI = new BUISpace($this);
        return $this->spaceUI;
    }

    public function load($data = NULL) {
        if ($data != NULL && is_numeric($data) && $data > 0) {
            $this->id = $data;
            return parent::load($data);
        }
        return parent::load($data);
    }

    public function save($data = NULL) {
        //   $count = BMSpace::model()->count();
        //$count = BRepositoryFactory::createRepository()->getCount($this);
        $count = $this->getRepository()->getCount();
        if ($count <= 0) {
            //first add types
            $spaceGroup = BSpaceGroup::getRoot();
            //add category group under root
            $spaceGroup->addChild(BSpaceGroup::Group_Category);
            $spaceCategory = BSpaceGroup::find(BSpaceGroup::Group_Category);
            $spaceCategory->addChildGroup(BSpaceGroup::Group_Category_General);
            $spaceCategory->addChildGroup(BSpaceGroup::Group_Category_Business);
            $spaceCategory->addChildGroup(BSpaceGroup::Group_Category_Public);
            $spaceCategory->addChildGroup(BSpaceGroup::Group_Category_NoneProfit);

            $spaceGroup->addChild(BSpaceGroup::Group_SpaceType);
            $spaceType = BSpaceGroup::find(BSpaceGroup::Group_SpaceType);
            $spaceType->addChildGroup(BSpaceGroup::Group_SpaceType_NormalSpace);
            $spaceType->addChildGroup(BSpaceGroup::Group_SpaceType_PersonalSpace);

            //add two special Space group
            $spaceGroup->addChild(BSpaceGroup::AllSpaces);
            $spaceGroup->addChild(BSpaceGroup::Not_Exit_Space);
        }

        //save dataObj for Space
        $spaceId = parent::save($data);
        $this->id = $spaceId;

        //add Space into category and type
        $sType = $this->getSpaceType();
        $sTypeName = NULL;
        if ($sType != NULL) {
            $sTypeName = $sType->getName();
        }
        $spaceType = isset($data['SpaceType']) ? $data['SpaceType'] : ($sTypeName == NULL ? BSpaceGroup::Group_SpaceType_NormalSpace : $sTypeName);
        $spaceCategory = isset($data['SpaceCategory']) ? $data['SpaceCategory'] : ($this->category == NULL ? BSpaceGroup::Group_Category_General : $this->category);

        $spaceTypeGroup = BSpaceGroup::find(BSpaceGroup::Group_SpaceType . '.' . $spaceType);
        $spaceTypeGroup->addMember($this);

        $spaceCategoryGroup = BSpaceGroup::find(BSpaceGroup::Group_Category . '.' . $spaceCategory);
        $spaceCategoryGroup->addMember($this);

        if ($spaceId > 0)
            return $spaceId;

        return FALSE;
    }

    public static function findUserSpaces($user) {

        if (is_numeric($user) && $user > 0) {
            $user = new BUser($user);
        }

        if ($user instanceof BUser) {
            $roles = BRole::findUserRoles($user, NULL, TRUE);
            $spaceListWithRoles = array();
            foreach ($roles as $role) {
                if ($role->spaceId != NULL && $role->spaceId > 0) {
                    if (!isset($spaceListWithRoles[$role->spaceId])) {
                        $spaceListWithRoles[$role->spaceId] = array();
                    }
                    array_push($spaceListWithRoles[$role->spaceId], $role);
                }
            }
            if ($spaceListWithRoles != NULL)
                return $spaceListWithRoles;
        }

        return FALSE;
    }

    public function run($data = NULL) {
        if (Blyn::app()->getActiveApp() instanceof BApp) {
            $app = Blyn::app()->getActiveApp();
            if (method_exists($app, 'runSpace')) {
                $app->runSpace($this, $data);
            }
        }
    }

    public function getSpaceRoleList($listFormat = 'stringList') {
        $roles = $this->getSpaceEngine()->getRoles();

        $list = array();
        if ($listFormat == 'stringList') {
            foreach ($roles as $id => $role) {
                $list[$id] = $role->getName(BEntity::Name_DisplayName);
            }
        } else if ($listFormat == 'adminOnly') {
            foreach ($roles as $id => $role) {
                $string = $role->getName(BEntity::Name_DisplayName);

                if (stristr($string, 'admin') == true) {
                    $list[$id] = $role->getName(BEntity::Name_DisplayName);
                }
            }
        }

        return $list;
    }

    public function getPropertyToColumnMapList($data = NULL) {
        $list = parent::getPropertyToColumnMapList($data);
        $list['myId'] = 'myid';
        return $list;
    }

    public function getRepository($data = NULL, $reload = FALSE) {
        $repository = parent::getRepository($data, $reload);
        $repository->addPropertyToColumnMap('myId', 'myid');
        return $repository;
    }

}

?>
